﻿using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Windows.Forms;


namespace _16_多线程框架
{
    public partial class Form1 : Form
    {
        Random rd = new Random();
        List<ThreadClass> threadClasses = new List<ThreadClass>();
        public Form1()
        {
            InitializeComponent();
            //取消跨线程访问控件检查
            Control.CheckForIllegalCrossThreadCalls = false;
            //设置指定控件的布局方式,设置控件跨4行
            tableLayoutPanel4.SetRowSpan(this.listBox1, 4);
        }

        private void Form1_Shown(object sender, EventArgs e)
        {
            //循环创建5个线程对象，并将其添加到集合中并绑定对应的按钮事件
            for (int i = 1; i <= 5; i++)
            {
                ThreadClass threadClass = new ThreadClass();
                threadClass.Name = "线程-"+ i.ToString();

                //在指定的容器中查找指定名称的控件
                //参数一:要查找的控件的名称
                //参数二:是否查找控件的子级（是否在容器中查找）
                //返回值:控件的集合=> .FirstOrDefault()  返回第一个查找到的控件  （Control类型）as Button:将查找到的控件转换为Button类型
                Button btnStart = tableLayoutPanel1.Controls.Find("btnStart" + i, true).FirstOrDefault() as Button;
                Button btnSuspend = tableLayoutPanel1.Controls.Find("btnSuspend" + i, true).FirstOrDefault() as Button;
                //进度条与进度文本
                ProgressBar progressBar = tableLayoutPanel1.Controls.Find("progressBar" + i, true).FirstOrDefault() as ProgressBar;
                Label lbl_value = tableLayoutPanel1.Controls.Find("lbl_value" + i, true).FirstOrDefault() as Label;

                ///为对象的StartAndAbortEvent事件绑定一个方法
                threadClass.StartAndAbortEvent += () => 
                {
                    if (btnStart.Text == "启 动")
                    {
                        btnStart.Text = "终 止";
                        btnSuspend.Enabled = true;//启用挂起按钮
                    }
                    else
                    {
                        btnStart.Text = "启 动";
                        btnSuspend.Enabled = false;//禁用挂起按钮
                    }
                };
                //为对象的SuspendedAndResumeEvent事件绑定一个方法
                threadClass.SuspendedAndResumeEvent += () =>
                {
                    if (btnSuspend.Text == "挂 起")
                    {
                        btnSuspend.Text = "唤 醒";
                        btnStart.Enabled = false;//禁用启动按钮
                    }
                    else
                    {
                        btnSuspend.Text = "挂 起";
                        btnStart.Enabled = true;//启用启动按钮
                    }
                };
                //为对象的RunEvent事件绑定一个方法  
                threadClass.RunEvent += (value) =>
                {
                    progressBar.Value = value;
                    lbl_value.Text = value.ToString() + "%";
                    //判断选择的是固定延时还是随机延时
                    if (this.radioButton1.Checked)
                    {
                        return int.Parse(this.textBox1.Text);
                    }
                    else
                    {
                        return rd.Next(int.Parse(this.textBox3.Text), int.Parse(this.textBox4.Text));
                    }
                };

                //启动与停止=>按钮绑定对应的事件
                btnStart.Click += (S, E) => 
                {
                    if (btnStart.Text == "启 动")
                    {
                        threadClass.Start();
                    }
                    else
                    {
                        threadClass.Abort();
                    }
                };
                //挂起与唤醒=>按钮绑定对应的事件
                btnSuspend.Click += (S, E) =>
                {
                    if (btnSuspend.Text == "挂 起")
                    {
                        threadClass.Suspend();
                    }
                    else
                    {
                        threadClass.Resume();
                    }
                };

                threadClasses.Add(threadClass);

            }
            //针对线程的批量操作
            foreach (Button btn in this.tableLayoutPanel2.Controls)
            {
                if (btn.Text == "线程启动") btn.Click += (S, E) =>
                {
                    threadClasses.ForEach(t=>t.Start());
                    //启动按钮设置为不可用
                    btn.Enabled = this.button15.Enabled = this.button13.Enabled = false;
                    //线程挂起与线程唤醒按钮设置为可用
                    this.button12.Enabled =  this.button14.Enabled = true;
                };
                if (btn.Text == "线程挂起") btn.Click += (S, E) => 
                {
                    threadClasses.ForEach(t => t.Suspend());
                    //线程挂起按钮设置为不可用
                    btn.Enabled = this.button14.Enabled = false;
                    //线程唤醒按钮设置为可用
                    this.button13.Enabled = true;
                };
                if (btn.Text == "线程唤醒") btn.Click += (S, E) =>
                {
                    threadClasses.ForEach(t => t.Resume());
                    //线程唤醒按钮设置为不可用
                    btn.Enabled =  false;
                    //线程挂起按钮设置为可用
                    this.button12.Enabled = this.button14.Enabled = true;
                };
                if (btn.Text == "线程终止") btn.Click += (S, E) => 
                {
                    threadClasses.ForEach(t => t.Abort());
                    btn.Enabled= this.button12.Enabled = false;
                    this.button11.Enabled  = this.button15.Enabled  = true;
                };
                if (btn.Text == "清空进度条") btn.Click += (S, E) => 
                {
                    for (int i = 1; i <= 5; i++)
                    {
                        //进度条
                        if(tableLayoutPanel1.Controls.Find("progressBar" + i, true).FirstOrDefault() is ProgressBar progressBar)  progressBar.Value=0;
                        //进度文本
                        if (tableLayoutPanel1.Controls.Find("lbl_value" + i, true).FirstOrDefault() is Label label) label.Text = "0%";
                    }
                };
            }


        }
        /// <summary>
        /// 同步到达
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void button1_Click(object sender, EventArgs e)
        {
            //获取所有线程中进度最快
            int max = threadClasses.Max(t => t.Value);
            //将进度最快的线程挂起
            threadClasses.FirstOrDefault(t => t.Value >= max).Suspend();

            Task.Run(() => 
            {
                do
                {
                    //循环检查所有线程对象，如果有大于或等于最大值那么就挂起
                    threadClasses.FindAll(t => t.Value == max && t.State != MyThreadState.Suspended).ForEach(t => t.Suspend());
                } while (threadClasses.FindAll(t => t.State == MyThreadState.Suspended).Count != threadClasses.Count);

                Thread.Sleep(50);

                //设置延时相同
                this.radioButton1.Checked = true;

                //获取按钮文本对象
                if (((Button)sender).Text == "同步到达")
                {
                    threadClasses.ForEach(t => t.Resume());
                }
                else
                {
                    foreach (string item in this.listBox1.Items)
                    {
                        threadClasses.Find(t => t.Name == item).Resume();
                        Thread.Sleep(int.Parse(this.textBox4.Text));
                    }
                }
            });

        }
    }
}
